<!--
 * @Author: 朱自强
 * @Date: 2024-03-12 19:12:14
 * @LastEditors: 朱自强
 * @LastEditTime: 2024-03-13 19:40:41
 * @FilePath: \A-LOT-OF-TEST-VUE3\src\views\SomeExample\AggridTable.vue
 * @Description: 
 * 
 * Copyright (c) 2024 by 朱自强, All Rights Reserved. 
-->
<template>
  <div
    id="aggrid-table-top-out-div"
    class="aggrid-table-top-out-div qc-common-out-div-theme"
    :class="`out-div${uuid}`"
  >
    <!-- 主div -->
    <div class="main-div qc-common-main-div-theme">
      <!-- 按钮 -->
      <div class="btn-div">
        <n-button type="primary">按钮</n-button>
      </div>
      <!-- 表格 -->
      <div class="table-div">
        <ag-grid-vue
          style="width: 100%; height: 100%"
          class="ag-theme-alpine"
          :columnDefs="columnDefs"
          :tooltipShowDelay="500"
          :rowData="rowData"
          :headerHeight="48"
          :defaultColDef="defaultColDef"
          :sideBar="sideBar"
          :getRowId="getRowId"
          :noRowsOverlayComponent="noRowsOverlayComponent"
          :noRowsOverlayComponentParams="noRowsOverlayComponentParams"
          :allowContextMenuWithControlKey="true"
          :getContextMenuItems="getContextMenuItems"
          :rowHeight="48"
          :enableRangeSelection="true"
          :stopEditingWhenCellsLoseFocus="true"
          overlayLoadingTemplate="数据加载中"
          @rowClicked="rowClicked"
          @cellClicked="cellClicked"
          @gridReady="onGridReady"
          @cellKeyDown="onCellKeyDown"
          @cellEditingStarted="onCellEditingStarted"
          @cellEditingStopped="onCellEditingStopped"
          @sortChanged="onSortChanged"
          @columnResized="onColumnResized"
          @columnVisible="onColumnVisible"
          @columnRowGroupChanged="onColumnRowGroupChanged"
          @columnValueChanged="onColumnValueChanged"
          @columnMoved="onColumnMoved"
          @columnPinned="onColumnPinned"
        />
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import type { Ref } from 'vue'
import type {
  GridReadyEvent,
  SideBarDef,
  GridApi,
  ColDef,
  ColGroupDef,
  ColumnApi,
  GetRowIdFunc,
  GetRowIdParams,
  GetContextMenuItems,
  MenuItemDef,
  RowClickedEvent,
  CellClickedEvent,
  CellKeyDownEvent,
  FullWidthCellKeyDownEvent,
  CellEditingStartedEvent,
  CellEditingStoppedEvent,
  SortChangedEvent,
  ColumnResizedEvent,
  ColumnVisibleEvent,
  ColumnRowGroupChangedEvent,
  ColumnValueChangedEvent,
  ColumnMovedEvent,
  ColumnPinnedEvent,
  ValueFormatterParams
} from 'ag-grid-community'
import { onMounted, onUnmounted, onBeforeMount, ref } from 'vue'
import { getUUID } from '@/utils/utils'
import AgNoRows from '@/components/Aggrid/AgNoRows'
import AgHeader from '@/components/Aggrid/AgHeader'
import AgRender from '@/components/Aggrid/AgRender'
// 唯一标识
const uuid: string = getUUID()
// 列定义
const columnDefs: Ref<ColDef[] | ColGroupDef[]> = ref([])
// 表格数据
const rowData: Ref<any[]> = ref([])
// 表格
const gridApi: Ref<GridApi | null> = ref(null)
// 表格列
const gridColumnApi: Ref<ColumnApi | null> = ref(null)
// 侧边栏
const sideBar: Ref<SideBarDef | null> = ref(null)
// 性别选项
const sexOptions = ref<Array<any>>([
  {
    label: '男',
    value: 1
  },
  {
    label: '女',
    value: 2
  }
])
// 默认列配置
const defaultColDef: Ref<ColDef> = ref({
  // 是否可以拖动列宽
  resizable: true,
  // 是否可以排序
  sortable: true,
  // 是否可过滤
  filter: true,
  // 列菜单filterMenuTab过滤菜单, generalMenuTab一般菜单, columnsMenuTab列菜单
  menuTabs: ['filterMenuTab', 'columnsMenuTab']
})
// 行id
const getRowId: Ref<GetRowIdFunc | null> = ref(null)
// 无数据组件名称
const noRowsOverlayComponent: Ref<any> = ref(null)
// 无数据组件名称配置
const noRowsOverlayComponentParams: Ref<any> = ref(null)
// 挂载前
onBeforeMount(() => {
  // 侧边栏
  sideBar.value = {
    toolPanels: [
      {
        id: 'columns',
        labelDefault: '列配置',
        labelKey: 'columns',
        iconKey: 'columns',
        toolPanel: 'agColumnsToolPanel',
        toolPanelParams: {
          suppressRowGroups: true,
          suppressValues: true,
          suppressPivots: true,
          suppressPivotMode: true,
          suppressColumnFilter: false,
          suppressColumnSelectAll: false,
          suppressColumnExpandAll: false
        }
      }
    ],
    position: 'left'
  }
  // 行id
  getRowId.value = function (e: GetRowIdParams): string {
    return e.data.id
  }
  // 自定义无数据组件
  noRowsOverlayComponent.value = AgNoRows
  // 自定义无数据组件参数
  noRowsOverlayComponentParams.value = {
    type: 'normalNoRows'
  }
})
// 挂载
onMounted(() => {})
// 表格加载完后
function onGridReady(e: GridReadyEvent): void {
  console.log(`表格加载完`, e)
  gridApi.value = e.api
  gridColumnApi.value = e.columnApi
  dealColumn()
}
// 处理列
function dealColumn(): void {
  // 组织列定义
  const columnDefs: ColDef[] | ColGroupDef[] = [
    {
      // 列名
      headerName: '序号',
      // 列字段名
      field: '',
      // 自定义列头渲染
      headerComponent: AgHeader,
      // 自定义列头渲染参数
      headerComponentParams: { edit: false },
      // 列宽
      width: 80,
      // 是否隐藏
      hide: false,
      // 单元格样式
      cellClass: 'text-center',
      // 数据显示格式化
      valueFormatter: (params: ValueFormatterParams): string => {
        const rowIndex: number | any = params.node?.rowIndex
        return rowIndex + 1 + ''
      }
    },
    {
      // 列名
      headerName: '姓名',
      // 列字段名
      field: 'name',
      // 自定义列头渲染
      headerComponent: AgHeader,
      // 自定义列头渲染参数
      headerComponentParams: { edit: true },
      // 是否可编辑
      editable: true,
      // 自带编辑框类型
      cellEditor: 'agTextCellEditor',
      // 编辑框参数
      cellEditorParams: {
        maxLength: 20
      },
      // 列宽
      width: 120,
      // 是否隐藏
      hide: false,
      // 单元格样式
      cellClass: 'text-center'
    },
    {
      // 列名
      headerName: '性别',
      // 列字段名
      field: 'sex',
      // 自定义列头渲染
      headerComponent: AgHeader,
      // 自定义列头渲染参数
      headerComponentParams: { edit: true },
      // 是否可编辑
      editable: true,
      // 自带编辑框类型
      cellEditor: 'agRichSelectCellEditor',
      // 编辑框参数
      cellEditorParams: {
        // 选项集合
        values: sexOptions.value.map((item: any): number => item.value),
        // 选项展示
        formatValue: (value: number): string => {
          const arr: Array<any> = sexOptions.value.filter(
            (item: any): boolean => item.value === value
          )
          return arr[0].label
        }
      },
      // 列宽
      width: 120,
      // 是否隐藏
      hide: false,
      // 单元格样式
      cellClass: 'text-center',
      // 数据显示格式化
      valueFormatter: (params: ValueFormatterParams): string =>
        sexOptions.value.filter((item: any): boolean => item.value === params.value)[0]?.label,
      cellRenderer: AgRender
    }
  ]
  // 加载列定义
  if (gridApi.value) {
    console.log(`加载列定义`, columnDefs)
    gridApi.value.setColumnDefs(columnDefs)
    // 加载数据
    loadData()
  }
}
// 加载数据
function loadData(): void {
  const data: any[] = [
    {
      id: 1,
      name: '姓名1',
      age: 18,
      sex: 1
    }
  ]
  if (gridApi.value) {
    console.log(`加载数据`, data)
    gridApi.value.setRowData(data)
  }
}
// 右键菜单
function getContextMenuItems(e: GetContextMenuItems): (string | MenuItemDef)[] {
  console.log(`右键菜单`, e)
  return [
    {
      name: '删除行',
      action: () => delRow(e),
      icon: '<i class="iconfont icon-xbj-lajitong" style="font-size: 16px"></i>'
    }
  ]
}
// 删除行
function delRow(e: GetContextMenuItems): void {
  console.log(`删除行`, e)
}
// 点击行
function rowClicked(e: RowClickedEvent): void {
  console.log(`点击行`, e)
}
// 点击单元格
function cellClicked(e: CellClickedEvent): void {
  console.log(`点击单元格`, e)
}
// 键盘点击
function onCellKeyDown(e: CellKeyDownEvent | FullWidthCellKeyDownEvent): void {
  console.log(`键盘点击`, e)
}
// 编辑开始
function onCellEditingStarted(e: CellEditingStartedEvent): void {
  console.log(`编辑开始`, e)
}
// 编辑结束
function onCellEditingStopped(e: CellEditingStoppedEvent): void {
  console.log(`编辑结束`, e)
}
// 列排序改变
function onSortChanged(e: SortChangedEvent): void {
  console.log(`列排序改变`, e)
}
// 列宽改变
function onColumnResized(e: ColumnResizedEvent): void {
  if (e.finished) {
    console.log(`列宽改变`, e)
  }
}
// 列显隐改变
function onColumnVisible(e: ColumnVisibleEvent): void {
  console.log(`列显隐改变`, e)
}
// 列分组改变
function onColumnRowGroupChanged(e: ColumnRowGroupChangedEvent): void {
  console.log(`列分组改变`, e)
}
// 列值改变
function onColumnValueChanged(e: ColumnValueChangedEvent): void {
  console.log(`列值改变`, e)
}
// 列移动
function onColumnMoved(e: ColumnMovedEvent): void {
  console.log(`列移动`, e)
}
// 列固钉
function onColumnPinned(e: ColumnPinnedEvent): void {
  console.log(`列固钉`, e)
}
// 卸载
onUnmounted(() => {})
</script>
<style lang="less" scoped>
.aggrid-table-top-out-div {
  // border: solid red 1px;
  .main-div {
    // border: solid blue 1px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    // 按钮
    .btn-div {
      // border: solid red 1px;
    }
    // 表格
    .table-div {
      // border: solid blue 1px;
      flex: 1;
    }
  }
}
</style>
<style></style>
